﻿using System;
using System.IO;
using System.Collections.Generic;

namespace K_Utils.K_Rename
{
	static class Program
	{
		private static bool waitKey;

		private static void Exit()
		{
			if (waitKey)
			{
				Console.Write("Press any key...");
				Console.ReadKey();
			}
			return;
		}

		private static void Help()
		{
			Console.WriteLine();
			Console.WriteLine("Usage: k-rename path mask pattern [options]");
			Console.WriteLine(@"Example: k-rename c:\mydata\pictures *.jpg yyMMdd-HHmmss -c -m -r -w");
			Console.WriteLine();
			Console.WriteLine("Options:");
			Console.WriteLine();
			Console.WriteLine("-?: Display help");
			Console.WriteLine("-h: Display help");
			Console.WriteLine("-c: Copy instead of rename");
			Console.WriteLine("-m: Use ModifiedTime instead of CreatedTime");
			Console.WriteLine("-r: Recursive (process all subdirectories)");
			Console.WriteLine("-w: Don't exit until key is pressed");
			Console.WriteLine();
			Console.WriteLine("Pattern components:");
			Console.WriteLine();
			Console.WriteLine("yy: The year without the century.");
			Console.WriteLine("yyyy: The year in four or five digits (depending on the calendar used), including the century.");
			Console.WriteLine("MM: The numeric month. Single-digit months have a leading zero.");
			Console.WriteLine("dd: The day of the month. Single-digit days have a leading zero.");
			Console.WriteLine("HH: The hour in a 24-hour clock. Single-digit hours have a leading zero.");
			Console.WriteLine("mm: The minute. Single-digit minutes have a leading zero.");
			Console.WriteLine("ss: The second. Single-digit seconds have a leading zero.");
			Console.WriteLine();
			Console.WriteLine("For more patterns see http://msdn2.microsoft.com/en-us/library/system.globalization.datetimeformatinfo.aspx");
			Exit();
		}

		private static void Main(string[] args)
		{
			List<string> argList = new List<string>(args);

			// init switches

			waitKey = argList.Contains("-w");
			bool copy = argList.Contains("-c");
			bool useModifiedTime = argList.Contains("-m");
			bool helpKey = argList.Contains("-h") || argList.Contains("-?");

			if (helpKey || argList.Count < 3)
			{
				Help();
				return;
			}

			string path = args[0];
			string mask = args[1];
			string pattern = args[2];

			// main body

			DirectoryInfo directory = new DirectoryInfo(path);
			if (directory.Exists)
				Console.WriteLine("Processing {0}\n", path);
			else
			{
				Console.WriteLine("Directory {0} does not exist", path);
				Exit();
			}

			FileInfo[] files = directory.GetFiles(mask, SearchOption.AllDirectories);
			List<string> errors = new List<string>();
			string action = copy ? " copied to " : " renamed to ";

			foreach (FileInfo file in files)
			{
				DateTime dateTime = useModifiedTime ? file.LastWriteTime : file.CreationTime;
				string newName = dateTime.ToString(pattern) + file.Extension;
				if (file.Name == newName)
					errors.Add(string.Format("{0} skipped:\nName is already compliant with pattern.\n", newName));
				else 
					try
					{
						if (copy)
							file.CopyTo(file.DirectoryName + "\\" + newName, false);
						else
							file.MoveTo(file.DirectoryName + "\\" + newName);
						Console.WriteLine(file.FullName + " successfully" + action + newName);
					}
					catch (Exception e)
					{
						errors.Add(string.Format("{0} could not be{1}{2}:\n{3}\n", file.FullName, action, newName, e.Message));
					}
			}
			Console.WriteLine();
			foreach (string error in errors)
				Console.WriteLine(error);
			Exit();
		}
	}
}
